package com.iwomy.secureplat.platform.controller;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.iwomy.secureplat.common.core.exception.PlatformBizErrorCodes;
import com.iwomy.secureplat.common.core.util.MsgUtils;
import com.iwomy.secureplat.common.core.util.R;
import com.iwomy.secureplat.common.log.annotation.SysLog;
import com.iwomy.secureplat.platform.dto.AlarmEventTypeDTO;
import com.iwomy.secureplat.platform.entity.AlarmEventTypeEntity;
import com.iwomy.secureplat.platform.entity.AlarmRulesEntity;
import com.iwomy.secureplat.platform.service.AlarmEventTypeService;
import com.iwomy.secureplat.platform.service.AlarmRulesService;
import org.springframework.security.access.prepost.PreAuthorize;
import com.iwomy.secureplat.common.excel.annotation.ResponseExcel;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.http.HttpHeaders;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;

/**
 * 报警事件类型
 *
 * @author pig
 * @date 2023-12-22 19:21:52
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/alarmEventType")
@Tag(description = "alarmEventType", name = "报警事件类型管理")
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class AlarmEventTypeController {

	private final AlarmEventTypeService alarmEventTypeService;

	private final AlarmRulesService alarmRulesService;


	/**
	 * 分页查询
	 *
	 * @param page           分页对象
	 * @param alarmEventType 报警事件类型
	 * @return
	 */
	@Operation(summary = "分页查询", description = "分页查询")
	@GetMapping("/page")
	@PreAuthorize("@pms.hasPermission('platform_alarmEventType_view')")
	public R getAlarmEventTypePage(@ParameterObject Page page, @ParameterObject AlarmEventTypeEntity alarmEventType) {
		LambdaQueryWrapper<AlarmEventTypeEntity> wrapper = Wrappers.lambdaQuery(alarmEventType);
		return R.ok(alarmEventTypeService.page(page, wrapper));
	}

	/**
	 * 列表查询
	 *
	 * @param alarmEventType 报警事件类型
	 * @return
	 */
	@Operation(summary = "列表查询", description = "列表查询")
	@GetMapping("/list")
	@PreAuthorize("@pms.hasPermission('platform_alarmEventType_view')")
	public R getAlarmEventTypeList(@ParameterObject AlarmEventTypeEntity alarmEventType) {
		LambdaQueryWrapper<AlarmEventTypeEntity> wrapper = Wrappers.lambdaQuery(alarmEventType);
		wrapper.eq(AlarmEventTypeEntity::getState, 20);
		return R.ok(alarmEventTypeService.list(wrapper));
	}


	/**
	 * 通过id查询报警事件类型
	 *
	 * @param id id
	 * @return R
	 */
	@Operation(summary = "通过id查询", description = "通过id查询")
	@GetMapping("/{id}")
	@PreAuthorize("@pms.hasPermission('platform_alarmEventType_view')")
	public R getById(@PathVariable("id") Long id) {
		return R.ok(alarmEventTypeService.getById(id));
	}

	/**
	 * 新增报警事件类型
	 *
	 * @param alarmEventType 报警事件类型
	 * @return R
	 */
	@Operation(summary = "新增报警事件类型", description = "新增报警事件类型")
	@SysLog("新增报警事件类型")
	@PostMapping
	@PreAuthorize("@pms.hasPermission('platform_alarmEventType_add')")
	public R save(@RequestBody AlarmEventTypeEntity alarmEventType) {
		LambdaQueryWrapper<AlarmEventTypeEntity> wrapper = Wrappers.lambdaQuery();
		wrapper.eq(AlarmEventTypeEntity::getProtocolName, alarmEventType.getProtocolName());
		wrapper.eq(AlarmEventTypeEntity::getAlarmTypeCode, alarmEventType.getAlarmTypeCode());
		wrapper.eq(AlarmEventTypeEntity::getEventTypeCode, alarmEventType.getEventTypeCode());
		AlarmEventTypeEntity one = alarmEventTypeService.getOne(wrapper);
		if (ObjectUtil.isNotNull(one)) {
			return R.failed("事件类型已存在");
		}

		return R.ok(alarmEventTypeService.save(alarmEventType));
	}

	/**
	 * 修改报警事件类型
	 *
	 * @param alarmEventType 报警事件类型
	 * @return R
	 */
	@Operation(summary = "修改报警事件类型", description = "修改报警事件类型")
	@SysLog("修改报警事件类型")
	@PutMapping
	@PreAuthorize("@pms.hasPermission('platform_alarmEventType_edit')")
	public R updateById(@RequestBody AlarmEventTypeEntity alarmEventType) {

		long count = alarmRulesService
				.count(Wrappers.lambdaQuery(new AlarmRulesEntity()).eq(AlarmRulesEntity::getEventTypeId, alarmEventType.getId()));
		if (count > 0) {
//			return R.failed("报警事件类型已被使用，无法编辑");
			return R.failed(MsgUtils.getMessage(PlatformBizErrorCodes.ALARM_EVENTTYPE_USED_MODIFY));
		}

		LambdaQueryWrapper<AlarmEventTypeEntity> wrapper = Wrappers.lambdaQuery();
		wrapper.eq(AlarmEventTypeEntity::getProtocolName, alarmEventType.getProtocolName());
		wrapper.eq(AlarmEventTypeEntity::getAlarmTypeCode, alarmEventType.getAlarmTypeCode());
		wrapper.eq(AlarmEventTypeEntity::getEventTypeCode, alarmEventType.getEventTypeCode());
		AlarmEventTypeEntity one = alarmEventTypeService.getOne(wrapper);

		if (ObjectUtil.isNotNull(one) && !one.getId().equals(alarmEventType.getId())) {
			return R.failed("事件类型已存在");
		}


		return R.ok(alarmEventTypeService.updateById(alarmEventType));
	}

	/**
	 * 通过id删除报警事件类型
	 *
	 * @param ids id列表
	 * @return R
	 */
	@Operation(summary = "通过id删除报警事件类型", description = "通过id删除报警事件类型")
	@SysLog("通过id删除报警事件类型")
	@DeleteMapping
	@PreAuthorize("@pms.hasPermission('platform_alarmEventType_del')")
	public R removeById(@RequestBody Long[] ids) {

		long count = alarmRulesService
				.count(Wrappers.lambdaQuery(new AlarmRulesEntity()).in(AlarmRulesEntity::getEventTypeId, ids));
		if (count > 0) {
//			return R.failed("报警事件类型已被使用，无法删除");
			return R.failed(MsgUtils.getMessage(PlatformBizErrorCodes.ALARM_EVENTTYPE_USED_DELETE));
		}
		return R.ok(alarmEventTypeService.removeBatchByIds(CollUtil.toList(ids)));
	}


	/**
	 * 导出excel 表格
	 *
	 * @param alarmEventType 查询条件
	 * @param ids            导出指定ID
	 * @return excel 文件流
	 */
	@ResponseExcel
	@GetMapping("/export")
	@PreAuthorize("@pms.hasPermission('platform_alarmEventType_export')")
	public List<AlarmEventTypeEntity> export(AlarmEventTypeEntity alarmEventType, Long[] ids) {
		return alarmEventTypeService.list(Wrappers.lambdaQuery(alarmEventType).in(ArrayUtil.isNotEmpty(ids), AlarmEventTypeEntity::getId, ids));
	}

	/**
	 * 启用禁用
	 *
	 * @param alarmEventTypeDTO
	 * @return R
	 */
	@Operation(summary = "启用禁用报警事件类型", description = "启用禁用报警事件类型")
	@SysLog(expression = "'启用禁用报警事件类型'.concat(#alarmProcessTypeDTO.remarks)")
	@PostMapping("/enableOrDisable")
	public R enableOrDisable(@RequestBody AlarmEventTypeDTO alarmEventTypeDTO) {
		AlarmEventTypeEntity alarmEventTypeEntity = new AlarmEventTypeEntity();
		alarmEventTypeEntity.setId(alarmEventTypeDTO.getId());
		alarmEventTypeEntity.setState(alarmEventTypeDTO.getState());
		return R.ok(alarmEventTypeService.updateById(alarmEventTypeEntity));
	}

	/**
	 * 获取事件类型和规则列表用于设备详情、报警记录下拉框
	 *
	 * @return
	 */
	@Operation(summary = "列表查询", description = "列表查询")
	@GetMapping("/eventTypeAndRuleList")
	public R eventTypeAndRuleList() {
		List list = new LinkedList<>();
		//心跳
		AlarmEventTypeEntity heartbeat = new AlarmEventTypeEntity();
		heartbeat.setProtocolName("empaer");
		heartbeat.setAlarmTypeCode("HEARTBEAT");
		heartbeat.setAlarmTypeName("心跳");
		heartbeat.setEventTypeCode("HEARTBEAT");
		heartbeat.setEventTypeName("心跳");
		list.add(heartbeat);
		//联网超时
		AlarmEventTypeEntity timeout = new AlarmEventTypeEntity();
		timeout.setProtocolName("empaer");
		timeout.setAlarmTypeCode("TIMEOUT");
		timeout.setAlarmTypeName("联网超时");
		timeout.setEventTypeCode("TIMEOUT");
		timeout.setEventTypeName("联网超时");
		list.add(timeout);
		//设备、故障报警
		List<AlarmEventTypeEntity> alarmEventTypeList = alarmEventTypeService.list();
		list.addAll(alarmEventTypeList);
		//规则报警
		List<AlarmRulesEntity> alarmRulesList = alarmRulesService.list();
		List<AlarmEventTypeEntity> alarmRuleList = alarmRulesList.stream().map(x -> {
			AlarmEventTypeEntity alarmRule = new AlarmEventTypeEntity();
			alarmRule.setProtocolName("empaer");
			alarmRule.setAlarmTypeCode("RULES_ALARM");
			alarmRule.setAlarmTypeName("规则报警");
			alarmRule.setEventTypeCode(x.getRuleName());
			alarmRule.setEventTypeName(x.getRuleName());
			return alarmRule;
		}).collect(Collectors.toList());
		list.addAll(alarmRuleList);

		return R.ok(list);
	}


}